package com.tsfyun.scm.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tsfyun.common.base.enums.RateTimeEnum;
import com.tsfyun.common.base.enums.RateTypeEnum;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.DateUtils;
import com.tsfyun.common.base.util.LocalDateTimeUtils;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TypeUtils;
import com.tsfyun.common.base.vo.CurrencyVO;
import com.tsfyun.scm.system.entity.BankChinaRate;
import com.tsfyun.scm.system.entity.CustomsRate;
import com.tsfyun.scm.system.mapper.BankChinaRateMapper;
import com.tsfyun.scm.system.service.IBankChinaRateService;
import com.tsfyun.scm.system.service.ICurrencyService;
import com.tsfyun.scm.system.service.ICustomsRateService;
import com.tsfyun.scm.system.service.IRateService;
import com.tsfyun.scm.system.vo.IndexCustomsRatePlusVO;
import com.tsfyun.scm.system.vo.IndexHalfMonthRateVO;
import com.tsfyun.scm.system.vo.PeriodBankChinaRateVO;
import com.tsfyun.scm.system.vo.RateSimpleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @CreateDate: Created in 2020/5/31 16:20
 */
@Service
public class RateServiceImpl implements IRateService {

    @Autowired
    private ICurrencyService currencyService;

    @Autowired
    private ICustomsRateService customsRateService;

    @Autowired
    private IBankChinaRateService bankChinaRateService;

    @Autowired
    private BankChinaRateMapper bankChinaRateMapper;

    @Override
    public Map<String, List<RateSimpleVO>> currentRate(String rateTime) {
        final String calRateTime = TypeUtils.castToString(rateTime, RateTimeEnum.TIME1.getCode());
        Optional.ofNullable(RateTimeEnum.of(calRateTime)).orElseThrow(()->new ServiceException("汇率时间错误"));
        //获取所有的币制
        List<CurrencyVO> currencys = currencyService.select();
        if(CollUtil.isEmpty(currencys)) {
            return null;
        }
        //过滤掉人民币
        currencys = currencys.stream().filter(r->!Objects.equals(r.getId(),"CNY")).collect(Collectors.toList());
        Map<String,List<RateSimpleVO>> rateMap = Maps.newHashMap();
        List<RateSimpleVO> customsRateList = Lists.newArrayList();
        List<RateSimpleVO> bankChinaRateList = Lists.newArrayList();
        //海关汇率
        List<CustomsRate> customsRates = customsRateService.getNowAllCurrencyRate();
        if(CollUtil.isNotEmpty(customsRates)) {
            customsRates = customsRates.stream().sorted(Comparator.comparing(CustomsRate::getCurrencyId).reversed()).collect(Collectors.toList());
        }
        customsRates.stream().forEach(customsRate -> {
            RateSimpleVO rateSimpleVO = new RateSimpleVO();
            rateSimpleVO.setCurrencyCode(customsRate.getCurrencyId());
            rateSimpleVO.setCurrencyName(customsRate.getCurrencyName());
            rateSimpleVO.setRate(StringUtils.isEmpty(customsRate.getRate()) ? "-" : StringUtils.null2EmptyWithTrim(customsRate.getRate()));
            customsRateList.add(rateSimpleVO);
        });
        //获取当天的中行汇率
        LocalDateTime now = LocalDateTime.now();
        String startTime = LocalDateTimeUtils.formatTime(now,"yyyy-MM-dd 00:00:00");
        List<PeriodBankChinaRateVO> bankChinaRates = bankChinaRateMapper.getPeriodRates(calRateTime.replace(":",""),startTime);
        Map<String,List<PeriodBankChinaRateVO>> periodBankChinaRatesMap = bankChinaRates.stream().collect(Collectors.groupingBy(PeriodBankChinaRateVO::getCurrencyId));
        currencys.stream().forEach(currencyVO -> {
            List<PeriodBankChinaRateVO> periodBankChinaRateVOS = periodBankChinaRatesMap.get(currencyVO.getId());
            if(CollUtil.isNotEmpty(periodBankChinaRateVOS)) {
                periodBankChinaRateVOS.stream().forEach(bankChinaRate->{
                    RateSimpleVO rateSimpleVO = new RateSimpleVO();
                    rateSimpleVO.setCurrencyCode(currencyVO.getId());
                    rateSimpleVO.setCurrencyName(currencyVO.getName());
                    //优先取现汇卖出价 再取 现钞卖出价
                    BigDecimal rate = Objects.nonNull(bankChinaRate.getSpotSelling()) ? bankChinaRate.getSpotSelling() : bankChinaRate.getCashSelling();
                    rate =  rate.divide(BigDecimal.valueOf(100),6,BigDecimal.ROUND_HALF_UP);
                    rateSimpleVO.setRate(rate.toString());
                    bankChinaRateList.add(rateSimpleVO);
                });
            } else {
                RateSimpleVO rateSimpleVO = new RateSimpleVO();
                rateSimpleVO.setCurrencyCode(currencyVO.getId());
                rateSimpleVO.setCurrencyName(currencyVO.getName());
                rateSimpleVO.setRate("-");
                bankChinaRateList.add(rateSimpleVO);
            }
        });
        rateMap.put("customsRate",customsRateList);
        rateMap.put("bankRate",bankChinaRateList);
        return rateMap;
    }

    @Override
    public IndexCustomsRatePlusVO customsExchangeRate(String rateMonth) {
        Date outDate = DateUtils.getDayStart(new Date());
        List<String> rateMonths = new ArrayList<>();
        for(int i=0;i<12;i++){
            rateMonths.add(DateUtils.format(DateUtils.addMonths(outDate,-1*i),"yyyy-MM"));
        }
        if(StringUtils.isEmpty(rateMonth)){
            rateMonth = rateMonths.get(0);
        }
        IndexCustomsRatePlusVO result = new IndexCustomsRatePlusVO();
        result.setRateMonth(rateMonth);
        result.setRateMonths(rateMonths);
        result.setCustomsRates(customsRateService.clientCustomsRate(rateMonth));
        return result;
    }

    @Override
    public List<RateSimpleVO> obcRate(String spotSelling, String obcRateTime,String rateDate) {
        //获取所有的币制
        List<CurrencyVO> currencys = currencyService.select();
        if(CollUtil.isEmpty(currencys)) {
            return null;
        }
        //过滤掉人民币
        currencys = currencys.stream().filter(r->!Objects.equals(r.getId(),"CNY")).collect(Collectors.toList());
        List<PeriodBankChinaRateVO> bankChinaRates = bankChinaRateMapper.getCurrentDateRates(obcRateTime.replace(":",""),TypeUtils.castToString(rateDate,DateUtils.formatShort(new Date())));
        Map<String,List<PeriodBankChinaRateVO>> periodBankChinaRatesMap = bankChinaRates.stream().collect(Collectors.groupingBy(PeriodBankChinaRateVO::getCurrencyId));
        List<RateSimpleVO> bankChinaRateList = Lists.newArrayList();
        currencys.stream().forEach(currencyVO -> {
            List<PeriodBankChinaRateVO> periodBankChinaRateVOS = periodBankChinaRatesMap.get(currencyVO.getId());
            if(CollUtil.isNotEmpty(periodBankChinaRateVOS)) {
                periodBankChinaRateVOS.stream().forEach(bankChinaRate->{
                    RateSimpleVO rateSimpleVO = new RateSimpleVO();
                    rateSimpleVO.setCurrencyCode(currencyVO.getId());
                    rateSimpleVO.setCurrencyName(currencyVO.getName());
                    BigDecimal rate = BigDecimal.ZERO;
                    switch (spotSelling){
                        case "spotSelling":// 现汇卖出价
                            //优先取现汇卖出价 再取 现钞卖出价
                            rate = Objects.nonNull(bankChinaRate.getSpotSelling()) ? bankChinaRate.getSpotSelling() : bankChinaRate.getCashSelling();
                            break;
                        case "buyingRate":// 现汇买入价
                            //优先取现汇买入价 再取 现钞买出价
                            rate = Objects.nonNull(bankChinaRate.getBuyingRate()) ? bankChinaRate.getSpotSelling() : bankChinaRate.getCashPurchase();
                            break;
                    }
                    rate =  rate.divide(BigDecimal.valueOf(100),6,BigDecimal.ROUND_HALF_UP);
                    rateSimpleVO.setRate(rate.toString());
                    bankChinaRateList.add(rateSimpleVO);
                });
            } else {
                RateSimpleVO rateSimpleVO = new RateSimpleVO();
                rateSimpleVO.setCurrencyCode(currencyVO.getId());
                rateSimpleVO.setCurrencyName(currencyVO.getName());
                rateSimpleVO.setRate("-");
                bankChinaRateList.add(rateSimpleVO);
            }
        });
        return bankChinaRateList;
    }
}
